package com.zxt.content.copywriting.events.upload;

import com.zxt.content.common.utils.ZXTCollectionsUtil;
import com.zxt.content.copywriting.enums.CopywritingStatusEnum;
import com.zxt.content.copywriting.manager.CopywritingTypeRelationManager;
import com.zxt.content.copywriting.manager.PrivateCopywritingManager;
import com.zxt.content.copywriting.manager.PublicCopywritingManager;
import com.zxt.content.copywriting.model.CopywritingTypeRelation;
import com.zxt.content.copywriting.model.PrivateCopywriting;
import com.zxt.content.copywriting.model.PublicCopywriting;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.ApplicationListener;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * 上传文案到公共文案 保存公共文案
 *
 * @author zxt
 */
@Component
@Slf4j
@Order(3) //设置执行顺序的排序
public class SavePublicCopywritingListener implements ApplicationListener<UploadCopywritingEvent> {

    private final PublicCopywritingManager publicCopywritingManager;
    private final PrivateCopywritingManager privateCopywritingManager;
    private final CopywritingTypeRelationManager copywritingTypeRelationManager;

    public SavePublicCopywritingListener(PublicCopywritingManager publicCopywritingManager, PrivateCopywritingManager privateCopywritingManager, CopywritingTypeRelationManager copywritingTypeRelationManager) {
        this.publicCopywritingManager = publicCopywritingManager;
        this.privateCopywritingManager = privateCopywritingManager;
        this.copywritingTypeRelationManager = copywritingTypeRelationManager;
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.DEFAULT, rollbackFor = Exception.class)
    public void onApplicationEvent(UploadCopywritingEvent uploadCopywritingEvent) {
        log.info("上传文案到公共文案--保存公共文案");

        UploadCopywritingEventContext context = uploadCopywritingEvent.getContext();

        List<PrivateCopywriting> privateCopywritings = context.getPrivateCopywritings();

        List<String> themes = privateCopywritings.stream().map(PrivateCopywriting::getTheme).collect(Collectors.toList());

        List<PublicCopywriting> existPublicwritings = publicCopywritingManager.listByThemesAndUserId(themes, context.getUserInfoApiVO().getId());
        Map<String, PublicCopywriting> publicCopywritingMap = Optional.ofNullable(existPublicwritings).orElse(new ArrayList<>()).stream().collect(Collectors.toMap(PublicCopywriting::getTheme, Function.identity()));


        //根据私人文案id进行分组，拿到关于文案的所有关联关系
        List<CopywritingTypeRelation> copywritingTypeRelations = context.getCopywritingTypeRelations();
        Map<Long, List<CopywritingTypeRelation>> copywritingTypeRelationGroup = copywritingTypeRelations.stream().collect(Collectors.groupingBy(CopywritingTypeRelation::getCopywritingId));

        List<PublicCopywriting> saveList = new ArrayList<>();
        List<PublicCopywriting> updateList = new ArrayList<>();
        for (PrivateCopywriting privateCopywriting : privateCopywritings) {
            PublicCopywriting savePublicCopywriting = new PublicCopywriting();
            savePublicCopywriting.setPrivateCopywritingId(privateCopywriting.getId());
            savePublicCopywriting.setTheme(privateCopywriting.getTheme());
            savePublicCopywriting.setContent(privateCopywriting.getContent());
            savePublicCopywriting.setAuthor(privateCopywriting.getAuthor());
            savePublicCopywriting.setUserId(privateCopywriting.getUserId());
            savePublicCopywriting.setSource(privateCopywriting.getSource());
            savePublicCopywriting.setNotes(privateCopywriting.getNotes());
            savePublicCopywriting.setImageUrl(privateCopywriting.getImageUrl());

            PublicCopywriting publicCopywriting = publicCopywritingMap.get(privateCopywriting.getTheme());
            if (Objects.nonNull(publicCopywriting)) {
                //将原有的公共文案id移过来
                savePublicCopywriting.setId(publicCopywriting.getId());
                updateList.add(savePublicCopywriting);
            } else {
                saveList.add(savePublicCopywriting);
            }
        }


        if (ZXTCollectionsUtil.isNotEmpty(updateList)) {
            /**
             * 批量修改公共文案
             */
            publicCopywritingManager.updateBatchById(updateList);
        }


        if (ZXTCollectionsUtil.isNotEmpty(saveList)) {
            /**
             * 批量保存并返回保存后的Id
             */
            publicCopywritingManager.saveBatchAndReturnId(saveList);
        }


        List<Long> existPublicCopywritingIds = existPublicwritings.stream().map(PublicCopywriting::getId).collect(Collectors.toList());

        //删除原公共文案的类型关联关系
        if (ZXTCollectionsUtil.isNotEmpty(existPublicCopywritingIds)) {
            copywritingTypeRelationManager.removeByPublicCopywritingIds(existPublicCopywritingIds);
            saveList.addAll(updateList);
        }


        List<CopywritingTypeRelation> newList = new ArrayList<>();
        for (PublicCopywriting publicCopywriting : saveList) {
            List<CopywritingTypeRelation> copywritingTypeRelationList = copywritingTypeRelationGroup.get(publicCopywriting.getPrivateCopywritingId());
            for (CopywritingTypeRelation copywritingTypeRelation : copywritingTypeRelationList) {
                CopywritingTypeRelation typeRelation = new CopywritingTypeRelation();
                typeRelation.setCopywritingId(publicCopywriting.getId());
                typeRelation.setIsPublic(Boolean.TRUE);
                typeRelation.setTypeId(copywritingTypeRelation.getTypeId());
                newList.add(typeRelation);
            }
        }
        //保存公共文案新的关联关系
        copywritingTypeRelationManager.saveBatch(newList);


        //修改私有文案上传状态
        List<Long> privateCopywritingIds = privateCopywritings.stream().map(PrivateCopywriting::getId).collect(Collectors.toList());
        privateCopywritingManager.updateStatusByIds(privateCopywritingIds, CopywritingStatusEnum.AUDIT_SUCCESS.getValue());

        context.setResult("success");
    }
}
